/*
-----------------------------------------------------------------------------
Filename:    BaseApplication.cpp
-----------------------------------------------------------------------------

This source file is part of the
   ___                 __    __ _ _    _ 
  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
/ \_// (_| | | |  __/  \  /\  /| |   <| |
\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
      |___/                              
      Tutorial Framework
      http://www.ogre3d.org/tikiwiki/
-----------------------------------------------------------------------------
*/
#include "BaseApplication.h"

//-------------------------------------------------------------------------------------
BaseApplication::BaseApplication(void)
    : mRoot(0),
    mCamera(0),
    mSceneMgr(0),
    mWindow(0),
    mResourcesCfg(Ogre::StringUtil::BLANK),
    mPluginsCfg(Ogre::StringUtil::BLANK),
    mTrayMgr(0),
    mCameraMan(0),
    mDetailsPanel(0),
    mCursorWasVisible(false),
    mShutDown(false),
    mInputManager(0),
    mMouse(0),
    mKeyboard(0),
	mMeshEntity(0),
	mAnimationState(0),
	mAttachedMeshEntity(0),
	mDirectionalLight(0)
{
}

//-------------------------------------------------------------------------------------
BaseApplication::~BaseApplication(void)
{
    if (mTrayMgr) delete mTrayMgr;
    if (mCameraMan) delete mCameraMan;

    //Remove ourself as a Window listener
    Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
    windowClosed(mWindow);
    delete mRoot;
}

//-------------------------------------------------------------------------------------
bool BaseApplication::configure(void)
{
    // Show the configuration dialog and initialise the system
    // You can skip this and use root.restoreConfig() to load configuration
    // settings if you were sure there are valid ones saved in ogre.cfg
    if(mRoot->showConfigDialog())
    {
        // If returned true, user clicked OK so initialise
        // Here we choose to let the system create a default rendering window by passing 'true'
        mWindow = mRoot->initialise(true, "Ogre3D Mesh and Animation Viewer");

        return true;
    }
    else
    {
        return false;
    }
}
//-------------------------------------------------------------------------------------
void BaseApplication::chooseSceneManager(void)
{
    // Get the SceneManager, in this case a generic one
    mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
}
//-------------------------------------------------------------------------------------
void BaseApplication::createCamera(void)
{
    // Create the camera
    mCamera = mSceneMgr->createCamera("PlayerCam");

    // Position it at 500 in Z direction
    mCamera->setPosition(Ogre::Vector3(0,0,80));
    // Look back along -Z
    mCamera->lookAt(Ogre::Vector3(0,0,0));
    mCamera->setNearClipDistance(5);

    mCameraMan = new OgreBites::SdkCameraMan(mCamera);   // create a default camera controller
}
//-------------------------------------------------------------------------------------
void BaseApplication::createFrameListener(void)
{
    Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
    OIS::ParamList pl;
    size_t windowHnd = 0;
    std::ostringstream windowHndStr;

    mWindow->getCustomAttribute("WINDOW", &windowHnd);
    windowHndStr << windowHnd;
    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

    mInputManager = OIS::InputManager::createInputSystem( pl );

    mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true ));
    mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));

    mMouse->setEventCallback(this);
    mKeyboard->setEventCallback(this);

    //Set initial mouse clipping size
    windowResized(mWindow);

    //Register as a Window listener
    Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);

    mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, mMouse, this);
    mTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT);
    mTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT);
    mTrayMgr->hideCursor();

    // create a params panel for displaying sample details
    Ogre::StringVector items;
    items.push_back("cam.pX");
    items.push_back("cam.pY");
    items.push_back("cam.pZ");
    items.push_back("");
    items.push_back("cam.oW");
    items.push_back("cam.oX");
    items.push_back("cam.oY");
    items.push_back("cam.oZ");
    items.push_back("");
    items.push_back("Filtering");
    items.push_back("Poly Mode");

    mDetailsPanel = mTrayMgr->createParamsPanel(OgreBites::TL_NONE, "DetailsPanel", 200, items);
    mDetailsPanel->setParamValue(9, "Bilinear");
    mDetailsPanel->setParamValue(10, "Solid");
    mDetailsPanel->hide();

    mRoot->addFrameListener(this);
}
//-------------------------------------------------------------------------------------
void BaseApplication::destroyScene(void)
{
}
//-------------------------------------------------------------------------------------
void BaseApplication::createViewports(void)
{
    // Create one viewport, entire window
    Ogre::Viewport* vp = mWindow->addViewport(mCamera);
    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));

    // Alter the camera aspect ratio to match the viewport
    mCamera->setAspectRatio(
        Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
}
//-------------------------------------------------------------------------------------
void BaseApplication::setupResources(void)
{
    // Load resource paths from config file
    Ogre::ConfigFile cf;
    cf.load(mResourcesCfg);

    // Go through all sections & settings in the file
    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();

    Ogre::String secName, typeName, archName;
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }
    }
}
//-------------------------------------------------------------------------------------
void BaseApplication::createResourceListener(void)
{

}
//-------------------------------------------------------------------------------------
void BaseApplication::loadResources(void)
{
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
//-------------------------------------------------------------------------------------
void BaseApplication::go(void)
{
#ifdef _DEBUG
    mResourcesCfg = "resources_d.cfg";
    mPluginsCfg = "plugins_d.cfg";
#else
    mResourcesCfg = "resources.cfg";
    mPluginsCfg = "plugins.cfg";
#endif

    if (!setup())
        return;

    mRoot->startRendering();

    // clean up
    destroyScene();
}
//-------------------------------------------------------------------------------------
bool BaseApplication::setup(void)
{
    mRoot = new Ogre::Root(mPluginsCfg);

    setupResources();

    bool carryOn = configure();
    if (!carryOn) return false;

    chooseSceneManager();
    createCamera();
    createViewports();

    // Set default mipmap level (NB some APIs ignore this)
    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);

    // Create any resource listeners (for loading screens)
    createResourceListener();
    // Load resources
    loadResources();

    // Create the scene
    createScene();

    createFrameListener();

    return true;
};
//-------------------------------------------------------------------------------------
bool BaseApplication::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    if(mWindow->isClosed())
        return false;

    if(mShutDown)
        return false;

    //Need to capture/update each device
    mKeyboard->capture();
    mMouse->capture();

    mTrayMgr->frameRenderingQueued(evt);

    if (!mTrayMgr->isDialogVisible())
    {
        mCameraMan->frameRenderingQueued(evt);   // if dialog isn't up, then update the camera
        if (mDetailsPanel->isVisible())   // if details panel is visible, then update its contents
        {
            mDetailsPanel->setParamValue(0, Ogre::StringConverter::toString(mCamera->getDerivedPosition().x));
            mDetailsPanel->setParamValue(1, Ogre::StringConverter::toString(mCamera->getDerivedPosition().y));
            mDetailsPanel->setParamValue(2, Ogre::StringConverter::toString(mCamera->getDerivedPosition().z));
            mDetailsPanel->setParamValue(4, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().w));
            mDetailsPanel->setParamValue(5, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().x));
            mDetailsPanel->setParamValue(6, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().y));
            mDetailsPanel->setParamValue(7, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().z));
        }
    }

	mGui->injectFrameEntered(evt.timeSinceLastFrame);
	if(mAnimationState){
		mAnimationState->addTime(evt.timeSinceLastFrame);
	}

    return true;
}
//-------------------------------------------------------------------------------------
bool BaseApplication::keyPressed( const OIS::KeyEvent &arg )
{
	mGui->injectKeyPress(arg);
	mControlPressed = false;

    if (mTrayMgr->isDialogVisible()) return true;   // don't process any more keys if dialog is up

    if (arg.key == OIS::KC_F)   // toggle visibility of advanced frame stats
    {
        mTrayMgr->toggleAdvancedFrameStats();
    }
    else if (arg.key == OIS::KC_G)   // toggle visibility of even rarer debugging details
    {
        if (mDetailsPanel->getTrayLocation() == OgreBites::TL_NONE)
        {
            mTrayMgr->moveWidgetToTray(mDetailsPanel, OgreBites::TL_TOPRIGHT, 0);
            mDetailsPanel->show();
        }
        else
        {
            mTrayMgr->removeWidgetFromTray(mDetailsPanel);
            mDetailsPanel->hide();
        }
    }
    else if (arg.key == OIS::KC_T)   // cycle polygon rendering mode
    {
        Ogre::String newVal;
        Ogre::TextureFilterOptions tfo;
        unsigned int aniso;

        switch (mDetailsPanel->getParamValue(9).asUTF8()[0])
        {
        case 'B':
            newVal = "Trilinear";
            tfo = Ogre::TFO_TRILINEAR;
            aniso = 1;
            break;
        case 'T':
            newVal = "Anisotropic";
            tfo = Ogre::TFO_ANISOTROPIC;
            aniso = 8;
            break;
        case 'A':
            newVal = "None";
            tfo = Ogre::TFO_NONE;
            aniso = 1;
            break;
        default:
            newVal = "Bilinear";
            tfo = Ogre::TFO_BILINEAR;
            aniso = 1;
        }

        Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
        Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(aniso);
        mDetailsPanel->setParamValue(9, newVal);
    }
    else if (arg.key == OIS::KC_R)   // cycle polygon rendering mode
    {
        Ogre::String newVal;
        Ogre::PolygonMode pm;

        switch (mCamera->getPolygonMode())
        {
        case Ogre::PM_SOLID:
            newVal = "Wireframe";
            pm = Ogre::PM_WIREFRAME;
            break;
        case Ogre::PM_WIREFRAME:
            newVal = "Points";
            pm = Ogre::PM_POINTS;
            break;
        default:
            newVal = "Solid";
            pm = Ogre::PM_SOLID;
        }

        mCamera->setPolygonMode(pm);
        mDetailsPanel->setParamValue(10, newVal);
    }
	else if( arg.key == OIS::KC_S )
	{
		if(mMeshEntity){
			//mMeshEntity->setVisible(!mMeshEntity->getVisible());
			mMeshEntity->setDisplaySkeleton(!mMeshEntity->getDisplaySkeleton());
		}
	}
    else if(arg.key == OIS::KC_F5)   // refresh all textures
    {
        Ogre::TextureManager::getSingleton().reloadAll();
    }
    else if (arg.key == OIS::KC_SYSRQ)   // take a screenshot
    {
        mWindow->writeContentsToTimestampedFile("screenshot", ".jpg");
    }
    else if (arg.key == OIS::KC_ESCAPE)
    {
        mShutDown = true;
    }

    mCameraMan->injectKeyDown(arg);
    return true;
}

bool BaseApplication::keyReleased( const OIS::KeyEvent &arg )
{
	if( arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL )
	{
		mControlPressed = !mControlPressed;
		return true;
	}

	mGui->injectKeyRelease(arg);
    mCameraMan->injectKeyUp(arg);
    return true;
}

bool BaseApplication::mouseMoved( const OIS::MouseEvent &arg )
{
	mGui->injectMouseMove(arg);

    if (mTrayMgr->injectMouseMove(arg)) return true;

	if( mControlPressed )
		mCameraMan->injectMouseMove(arg);
    return true;
}

bool BaseApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	mGui->injectMousePress(arg,id);

    if (mTrayMgr->injectMouseDown(arg, id)) return true;
    mCameraMan->injectMouseDown(arg, id);
    return true;
}

bool BaseApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	mGui->injectMouseRelease(arg, id);

    if (mTrayMgr->injectMouseUp(arg, id)) return true;
    mCameraMan->injectMouseUp(arg, id);
    return true;
}

//Adjust mouse clipping area
void BaseApplication::windowResized(Ogre::RenderWindow* rw)
{
    unsigned int width, height, depth;
    int left, top;
    rw->getMetrics(width, height, depth, left, top);

    const OIS::MouseState &ms = mMouse->getMouseState();
    ms.width = width;
    ms.height = height;
}

//Unattach OIS before window shutdown (very important under Linux)
void BaseApplication::windowClosed(Ogre::RenderWindow* rw)
{
    //Only close for window that created OIS (the main window in these demos)
    if( rw == mWindow )
    {
        if( mInputManager )
        {
            mInputManager->destroyInputObject( mMouse );
            mInputManager->destroyInputObject( mKeyboard );

            OIS::InputManager::destroyInputSystem(mInputManager);
            mInputManager = 0;
        }
    }
}

void BaseApplication::createGui()
{
	mGui = new MyGUI::Gui();
	
	mGui->initialise(mRoot->getAutoCreatedWindow(), "core.xml", "General" );
	mGui->setSceneManager(mSceneMgr);
	mGui->load("omav.layout", "General");

	mOptionsWindow = mGui->findWidget<MyGUI::Window>("optionsWindow");
	mMeshComboBox = mGui->findWidget<MyGUI::ComboBox>("meshList");
	mAnimComboBox = mGui->findWidget<MyGUI::ComboBox>("animList");
	mBoneListComboBox = mGui->findWidget<MyGUI::ComboBox>("boneList");
	mAttachedMeshComboBox = mGui->findWidget<MyGUI::ComboBox>("attachMeshList");
	mLightColorComboBox = mGui->findWidget<MyGUI::ComboBox>("backgroundcolor");
	mAttachLightBtn = mGui->findWidget<MyGUI::Button>("attachLightBtn");
	mDetachLightBtn = mGui->findWidget<MyGUI::Button>("detachLightBtn");
	mApplyQuaternionBtn = mGui->findWidget<MyGUI::Button>("quaternionApplyButton");
	mLightXPositionField = mGui->findWidget<MyGUI::Edit>("lightXField");
	mLightYPositionField = mGui->findWidget<MyGUI::Edit>("lightYField");
	mLightZPositionField = mGui->findWidget<MyGUI::Edit>("lightZField");
	mQuaternionXPositionField = mGui->findWidget<MyGUI::Edit>("quaternionXField");
	mQuaternionYPositionField = mGui->findWidget<MyGUI::Edit>("quaternionYField");
	mQuaternionZPositionField = mGui->findWidget<MyGUI::Edit>("quaternionZField");

	mMeshComboBox->eventComboChangePosition = MyGUI::newDelegate(this, &BaseApplication::onMeshComboBoxChange);
	mAnimComboBox->eventComboChangePosition = MyGUI::newDelegate(this, &BaseApplication::onAnimComboBoxChange);
	mBoneListComboBox->eventComboChangePosition = MyGUI::newDelegate(this, &BaseApplication::onBoneListComboBoxChange);
	mAttachedMeshComboBox->eventComboChangePosition = MyGUI::newDelegate(this, &BaseApplication::onAttachedMeshComboBoxChange); 
	mLightColorComboBox->eventComboChangePosition = MyGUI::newDelegate(this, &BaseApplication::onBackgroundColorComboBoxChange);
	mAttachLightBtn->eventMouseButtonClick = MyGUI::newDelegate(this, &BaseApplication::attachButtonPressed);
	mDetachLightBtn->eventMouseButtonClick = MyGUI::newDelegate(this, &BaseApplication::detachedButtonPressed);
	mApplyQuaternionBtn->eventMouseButtonClick = MyGUI::newDelegate(this, &BaseApplication::applyButtonPressed);
	mLightXPositionField->eventEditTextChange = MyGUI::newDelegate(this, &BaseApplication::fieldTextChanged);

	mOptionsWindow->setVisibleSmooth(true);
	mOptionsWindow->setPosition(0,0);

	mAnimComboBox->addItem("None");
	mAnimComboBox->setItemSelectedAt(0);
	mMeshComboBox->addItem("None");
	mMeshComboBox->setItemSelectedAt(0);

	mBoneListComboBox->addItem("None");
	mBoneListComboBox->setItemSelectedAt(0);
	mAttachedMeshComboBox->addItem("None");
	mAttachedMeshComboBox->setItemSelectedAt(0);

	mLightColorComboBox->addItem("None");
	mLightColorComboBox->addItem("Black");
	mLightColorComboBox->addItem("White");
	mLightColorComboBox->addItem("Cloudy Gray");
	mLightColorComboBox->addItem("Light Gray");
	mLightColorComboBox->addItem("Dark Gray");
	mLightColorComboBox->setItemSelectedAt(0);

	Ogre::StringVectorPtr resources = Ogre::ResourceGroupManager::getSingleton().findResourceNames("General", "*.mesh" );
	Ogre::StringVector::iterator it = resources->begin();
	for(it; it != resources->end(); it++){
		std::string name = *it;
		mMeshComboBox->addItem(name);
		mAttachedMeshComboBox->addItem(name);
	}

	mMeshSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("MeshNode");
}

void BaseApplication::onMeshComboBoxChange(MyGUI::WidgetPtr widget, size_t index)
{
	std::string meshName = mMeshComboBox->getItemNameAt(mMeshComboBox->getIndexSelected());
	if(meshName == "" || meshName == "None" )
		return;


	if(mMeshEntity) 
		mSceneMgr->destroyEntity(mMeshEntity);
	if(mAnimationState){
		mAnimationState->setEnabled(false);
		mAnimationState = 0;
	}

	mMeshEntity = mSceneMgr->createEntity(meshName, meshName);

	mMeshSceneNode->detachAllObjects();
	mMeshSceneNode->attachObject(mMeshEntity);
	mMeshSceneNode->setPosition(0,0,0);

	mAnimComboBox->removeAllItems();
	mAnimComboBox->addItem("None");
	mAnimComboBox->setItemSelectedAt(0);

	mBoneListComboBox->removeAllItems();
	mBoneListComboBox->addItem("None");
	mBoneListComboBox->setItemSelectedAt(0);


	Ogre::AnimationStateSet * ass = mMeshEntity->getAllAnimationStates();
	Ogre::AnimationStateIterator it = ass->getAnimationStateIterator();
	while(it.hasMoreElements()){
		std::string name = it.getNext()->getAnimationName();
		mAnimComboBox->addItem(name);
	}

	if(mMeshEntity->getSkeleton()){
		Ogre::Skeleton::BoneIterator bit =	mMeshEntity->getSkeleton()->getBoneIterator();
		while( bit.hasMoreElements() ){
			Ogre::String name = bit.getNext()->getName();

			mBoneListComboBox->addItem(name);
		}
	}
	mAnimComboBox->setItemSelectedAt(0);
	mBoneListComboBox->setItemSelectedAt(0);

}
void BaseApplication::onAnimComboBoxChange(MyGUI::WidgetPtr widget, size_t index)
{
	std::cout<<"fireup onAnimComboBoxChange"<<std::endl;

	std::string meshName = mMeshComboBox->getItemNameAt(mMeshComboBox->getIndexSelected());
	if(meshName == "" || meshName == "None" )
		return;
	
	std::string animName = mAnimComboBox->getItemNameAt(mAnimComboBox->getIndexSelected());
	if( animName == "" || animName == "None")
		return;

	if(mAnimationState){
		mAnimationState->setEnabled(false);
	}
	mAnimationState = mMeshEntity->getAnimationState(animName);
	mAnimationState->setLoop(true);
	mAnimationState->setEnabled(true);

}

void BaseApplication::onBoneListComboBoxChange(MyGUI::WidgetPtr widget, size_t index)
{
	std::string boneName = mBoneListComboBox->getItemNameAt(index);
	if( boneName == "" || boneName == "None" )
		return;


	mMeshEntity->detachAllObjectsFromBone();
	if(mAttachedMeshEntity){
		mMeshEntity->attachObjectToBone(boneName, mAttachedMeshEntity);
	}
	// if we have some mesh selected to attach to the bone we attach it, else we do nothing
	//size_t i = mAttachedMeshComboBox->getIndexSelected();
	//std::string selectedMeshName = mAttachedMeshComboBox->getItemNameAt(1);
	//
	//Ogre::LogManager::getSingleton().logMessage("======");
	//Ogre::LogManager::getSingleton().logMessage(selectedMeshName);
	//if( selectedMeshName == "" || selectedMeshName == "None" ) //if no selected mesh, do nothing
	//	return;

	//if( !mAttachedMeshEntity ) //if not selected mesh entity created, do nothing
	//	return;

	//mMeshEntity->attachObjectToBone( mBoneListComboBox->getItemNameAt(index), mAttachedMeshEntity );
	
}

void BaseApplication::onAttachedMeshComboBoxChange(MyGUI::WidgetPtr widget, size_t index)
{
	std::string selectedMeshName = mAttachedMeshComboBox->getItemNameAt(index);
	if( selectedMeshName == "" || selectedMeshName == "None" )
		return;

	if( !mAttachedMeshEntity ){
		mMeshEntity->detachAllObjectsFromBone();
		delete mAttachedMeshEntity;
		mAttachedMeshEntity = 0;
	}
	if( mMeshEntity->getName() == selectedMeshName )
		return;

	if( mMeshEntity->hasSkeleton() ){
		mSceneMgr->destroyEntity(selectedMeshName);
		mAttachedMeshEntity = mSceneMgr->createEntity(selectedMeshName, selectedMeshName);
		
		std::string boneName = mBoneListComboBox->getItemNameAt(mBoneListComboBox->getIndexSelected());
		if( boneName == "" || boneName == "None" )
			return;
		mMeshEntity->attachObjectToBone(boneName, mAttachedMeshEntity);
	}

}

void BaseApplication::onBackgroundColorComboBoxChange(MyGUI::WidgetPtr widget, size_t index)
{
	std::string selectedColorName = mLightColorComboBox->getItemNameAt(index);
	if( selectedColorName == "" || selectedColorName == "None")
		return;

	mWindow->removeAllViewports();
	Ogre::Viewport* vp = mWindow->addViewport(mCamera);

	if( selectedColorName == "Black") 
		vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

	else if( selectedColorName == "White")
		vp->setBackgroundColour(Ogre::ColourValue(1, 1, 1));

	else if( selectedColorName == "Cloudy Gray")
		vp->setBackgroundColour(Ogre::ColourValue(0.75, 0.75 , 0.75));

	else if( selectedColorName == "Light Gray")
		vp->setBackgroundColour(Ogre::ColourValue(0.85, 0.85, 0.85));

	else if( selectedColorName == "Dark Gray")
		vp->setBackgroundColour(Ogre::ColourValue(0.50, 0.50 , 0.50));
}

void BaseApplication::attachButtonPressed(MyGUI::WidgetPtr widget)
{
	if(mDirectionalLight)
		return;

	if(checkNumericValue(mLightXPositionField->getCaption()) == false)
		return;

	if(checkNumericValue(mLightYPositionField->getCaption()) == false)
		return;

	if(checkNumericValue(mLightZPositionField->getCaption()) == false)
		return;

	mDirectionalLight = mSceneMgr->createLight("spotLight");
    mDirectionalLight->setType(Ogre::Light::LT_SPOTLIGHT);
	mDirectionalLight->setPosition(Ogre::Vector3((stringToInteger(mLightYPositionField->getCaption()), stringToInteger(mLightYPositionField->getCaption()), stringToInteger(mLightZPositionField->getCaption()))));
	mDirectionalLight->setDirection(-1, -1, 0);
	mDirectionalLight->setSpotlightRange(Ogre::Degree(35), Ogre::Degree(50));
}

void BaseApplication::detachedButtonPressed(MyGUI::WidgetPtr widget)
{
	if(!mDirectionalLight)
		return;

	mSceneMgr->destroyAllLights();
	mDirectionalLight = 0;
}

void BaseApplication::applyCoordinateChange(void)
{
}

void BaseApplication::fieldTextChanged(MyGUI::WidgetPtr widget)
{
	if(!mDirectionalLight)
		return;

	if(checkNumericValue(mLightXPositionField->getCaption()) == false)
		return;



	if(checkNumericValue(mLightYPositionField->getCaption()) == false)
		return;

	if(checkNumericValue(mLightZPositionField->getCaption()) == false)
		return;
}

bool BaseApplication::checkNumericValue(std::string value)
{
	for(unsigned short int i = 0; i<value.length(); i++) {
		if(value[i] < 48 || value[i] > 57)
			return false;
	}

	return true;
}

int BaseApplication::stringToInteger(std::string str)
{
	int i;
	std::istringstream is(str);
	is>>i;

	return i;
}

void BaseApplication::applyButtonPressed(MyGUI::WidgetPtr widget)
{
	if(checkNumericValue(mQuaternionXPositionField->getCaption()) == false)
		return;

	if(checkNumericValue(mQuaternionYPositionField->getCaption()) == false)
		return;

	if(checkNumericValue(mQuaternionZPositionField->getCaption()) == false)
		return;

	Ogre::Vector3 * newVector = new Ogre::Vector3(stringToInteger(mQuaternionXPositionField->getCaption()), stringToInteger(mQuaternionYPositionField->getCaption()), stringToInteger(mQuaternionZPositionField->getCaption()));

	std::string boneName = mBoneListComboBox->getItemNameAt(mBoneListComboBox->getIndexSelected());
	if( boneName == "" || boneName == "None" )
			return;

	mMeshEntity->attachObjectToBone(boneName, mAttachedMeshEntity, newVector);

	delete newVector;
}

void BaseApplication::createGrid()
{
	mGrid = mSceneMgr->createManualObject("grid");

	Ogre::SceneNode * gridNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("gridNode");
	Ogre::MaterialManager &matMgr = Ogre::MaterialManager::getSingleton();
	if(!matMgr.resourceExists("GridMat"))
	{
		Ogre::MaterialPtr pMaterial = matMgr.create("GridMat", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
		pMaterial->setLightingEnabled(false);
		pMaterial->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
	}

	int numLines = 100;
	//mGrid->estimateVertexCount(4 * numLines);
	mGrid->begin("GridMat", Ogre::RenderOperation::OT_LINE_LIST);

	Ogre::Real start = -numLines/2;
	Ogre::Real x = start;
	while(x <= numLines / 2)
	{
			int multX = (x == 0) ? x : (x < 0) ? (int) (x / 1 - 0.5f) : (int) (x / 1 + 0.5f);
			Ogre::ColourValue colour = Ogre::ColourValue::White;

			mGrid->position(x, 0, - numLines /2 );
			mGrid->colour(colour);
			mGrid->position(x, 0, numLines/2 );

			mGrid->position( -numLines/2, 0, x );
			mGrid->colour(colour);
			mGrid->position( numLines/2, 0, x );
			mGrid->colour(colour);

			x += 1;
	}
	mGrid->end();
	gridNode->resetOrientation();
	

	gridNode->attachObject(mGrid);
	gridNode->setPosition(0, 0, 0);

}